
cmake_minimum_required(VERSION 3.20)

# This is the toolchain file, we use the arm-none-eabi toolchain
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/arm-gcc-toolchain.cmake)
include(${CMAKE_TOOLCHAIN_FILE})

# Enable export of compilation database for further analysis
# This creates a compile_comands.json file in the build directory that
# can be used by visual studio and cppcheck for code completion and
# build analysis.
# set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

###################### CONSTANTS ######################################
set (PROJECT_TYPE_EXECUTABLE          "exe")
set (PROJECT_TYPE_STATIC_LIBRARY      "static-lib")
set (MCPU_CORTEX_M0				      "-mcpu=cortex-m0")
set (MCPU_CORTEX_M0PLUS				  "-mcpu=cortex-m0plus")
set (MCPU_CORTEX_M3				      "-mcpu=cortex-m3")
set (MCPU_CORTEX_M4				      "-mcpu=cortex-m4")
set (MCPU_CORTEX_M7				      "-mcpu=cortex-m7")
set (MCPU_CORTEX_M33				  "-mcpu=cortex-m33")
set (MCPU_CORTEX_M55				  "-mcpu=cortex-m55")
set (MCPU_CORTEX_M85				  "-mcpu=cortex-m85")
set (MFPU_FPV4_SP_D16                 "-mfpu=fpv4-sp-d16")
set (MFPU_FPV5_D16                    "-mfpu=fpv5-d16")
set (RUNTIME_LIBRARY_REDUCED_C        "--specs=nano.specs")
set (RUNTIME_LIBRARY_STD_C            "")
set (RUNTIME_LIBRARY_SYSCALLS_MINIMAL "--specs=nosys.specs")
set (RUNTIME_LIBRARY_SYSCALLS_NONE    "")
set (MFLOAT_ABI_SOFTWARE              "-mfloat-abi=soft")
set (MFLOAT_ABI_HARDWARE              "-mfloat-abi=hard")
set (MFLOAT_ABI_MIX                   "-mfloat-abi=softfp")
set (LINK_SCRIPT_PATH              ${CMAKE_CURRENT_SOURCE_DIR}/link.lds)
set (STARTUP_FILE             ${CMAKE_CURRENT_SOURCE_DIR}/startup_stm32f407xx.S)

#######################################################################

###################### VARIABLES ######################################
set (PROJECT_NAME             "uav_gz")
set (PROJECT_TYPE             "exe")
set (LINKER_SCRIPT            ${LINK_SCRIPT_PATH})
set (MCPU                     ${MCPU_CORTEX_M4})
set (MFPU                     ${MFPU_FPV4_SP_D16})
set (MFLOAT_ABI               ${MFLOAT_ABI_MIX})
set (RUNTIME_LIBRARY          "--specs=nano.specs")
set (RUNTIME_LIBRARY_SYSCALLS "--specs=nosys.specs")
set (CMAKE_C_STANDARD 11)
set (CMAKE_C_STANDARD_REQUIRED ON)
set (CMAKE_INCLUDE_CURRENT_DIR OFF)
set (CMAKE_BUILD_TYPE         "Debug")

set (PROJECT_SOURCES
	  # LIST SOURCE FILES HERE
	  main.c
    ${STARTUP_FILE}
	)

set (PROJECT_DEFINES
	  # LIST COMPILER DEFINITIONS HERE
    USE_HAL_DRIVER STM32F407xx SOC_FAMILY_STM32 SOC_SERIES_STM32F4
    )

set (PROJECT_INCLUDES
	# LIST INCLUDE DIRECTORIES HERE
    )



#######################################################
#                Target
#######################################################
# 为了解决前面分析的问题，我们引入了标题中的几个参数。GCC链接操作是以section作为最小的处理单元，
# 只要一个section中的某个符号被引用，该section就会被加入到可执行程序中去。
# 因此，GCC在编译时可以使用 -ffunction-sections 和 -fdata-sections 将每个函数或符号创建为一个sections，
# 其中每个sections名与function或data名保持一致。而在链接阶段， -Wl,–gc-sections 
# 指示链接器去掉不用的section（其中-wl, 表示后面的参数 -gc-sections 传递给链接器），这样就能减少最终的可执行程序的大小了。

project(${PROJECT_NAME})
enable_language(ASM C)
add_compile_options(
  # -O3
  -ggdb
  -fdiagnostics-color=always
  -ffunction-sections
  -fdata-sections
  
)

if (${PROJECT_TYPE} MATCHES ${PROJECT_TYPE_EXECUTABLE})
  add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
  add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD 
  COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${CMAKE_PROJECT_NAME}>
  COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
  COMMAND ${CMAKE_OBJCOPY} -I binary -O ihex ${PROJECT_NAME}.bin ${PROJECT_NAME}.hex)

elseif (${PROJECT_TYPE} MATCHES ${PROJECT_TYPE_STATIC_LIBRARY})
  add_library(${PROJECT_NAME} ${PROJECT_SOURCES})
endif()

add_compile_definitions (${PROJECT_DEFINES})
include_directories (${PROJECT_INCLUDES})

add_subdirectory(libraries)
add_subdirectory(RT_Thread_Nano)
add_subdirectory(bsp)
add_subdirectory(sensor)
add_subdirectory(guidance)
add_subdirectory(communication)
add_subdirectory(misc)
add_subdirectory(control)

target_link_libraries(${PROJECT_NAME} m)
# 

set (CMAKE_EXECUTABLE_SUFFIX ".elf")
set (CMAKE_STATIC_LIBRARY_SUFFIX ".a")
set (CMAKE_C_FLAGS "${MCPU} -std=gnu11 ${MFPU} ${MFLOAT_ABI} ${RUNTIME_LIBRARY} -mthumb -Wall ")
set (CMAKE_EXE_LINKER_FLAGS "-T${LINKER_SCRIPT} ${RUNTIME_LIBRARY_SYSCALLS} -Wl,-Map=test.map  -Wl,--print-memory-usage -Wl,--gc-sections -Wl,--cref -static -Wl,--start-group -lc -lm -Wl,--end-group")
set (CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -Wa,-mimplicit-it=thumb")

# a custom target to facilitate the flashing of the device with ninja flash
add_custom_target(flash COMMAND
        openocd -f interface/cmsis-dap.cfg -f target/stm32f4x.cfg 
        -c "program uav_gz.elf verify reset exit"
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/build/${PROJECT_NAME}.elf
)
 
#######################################################
#            CMake Configuration Options
#######################################################

include(CMakePrintHelpers)
cmake_print_variables(CMAKE_VERSION)
cmake_print_variables(CMAKE_PREFIX_PATH)
cmake_print_variables(CMAKE_HOST_SYSTEM_NAME)
cmake_print_variables(CMAKE_HOST_SYSTEM_VERSION)
cmake_print_variables(CMAKE_SYSTEM_NAME)
cmake_print_variables(CMAKE_SYSTEM_VERSION)
cmake_print_variables(CMAKE_CURRENT_SOURCE_DIR)
cmake_print_variables(CMAKE_BUILD_TYPE)
cmake_print_variables(CMAKE_TOOLCHAIN_FILE)





